"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"wJjIP5Vne7cM"},"source":["Text is one of the most common forms of data your programs will handle. You already know how to concatenate two `string` together with the `+` operator, but you can do much more than that! You can extract partial strings from `string` just like sequence, add or remove spacing, convert letters to lowercase or uppercase, and check that `strings` are formatted correctly!"]},{"cell_type":"markdown","metadata":{"id":"SwFKFBMwRzoa"},"source":["## String"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"xtOzCNTJcj3N"},"source":["There are several ways to create a new `string`; the simplest is to enclose the elements in single or double quotes:"]},{"cell_type":"code","execution_count":17,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":4,"status":"ok","timestamp":1668686223113,"user":{"displayName":"phonchi chung","userId":"13517391734500420886"},"user_tz":-480},"id":"ossL66xxcoGg","outputId":"6fac1a14-1607-409b-c6f1-0b05188f6e2c"},"outputs":[{"data":{"text/plain":["(str, str)"]},"execution_count":17,"metadata":{},"output_type":"execute_result"}],"source":["type(''), type(\"\")"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["> One benefit of using double quotes is that the string can have a single quote character in it."]},{"cell_type":"code","execution_count":18,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["I'am fine\n"]}],"source":["print(\"I'am fine\")"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"Ss9hRGHDRzob"},"source":["A `string` is a **sequence that maps index to case sensitive characters and thus belongs to sequence data type**. Anything that we can apply to the sequence can also be applied to `string`. For instance, you can access the **items (characters)** one at a time with the bracket operator:"]},{"cell_type":"code","execution_count":19,"metadata":{"id":"4X-QB57Sqxbu"},"outputs":[{"data":{"text/plain":["'a'"]},"execution_count":19,"metadata":{},"output_type":"execute_result"}],"source":["fruit = 'banana'\n","fruit[1]"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"cc7LkxgesPQf"},"source":["So \"b\" is the 0th letter (\"zero-th\") of \"banana\", \"a\" is the 1th letter (\"one-th\"), and \"n\" is the 2th (\"two-th\") letter.\n","\n","
\n","
source: https://www.py4e.com/html3/06-strings
"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"GQ-v5PkhrxLt"},"source":["`len()` can be used to return the number of characters in a `string`:"]},{"cell_type":"code","execution_count":20,"metadata":{"id":"9eio5IH1sRe_"},"outputs":[{"data":{"text/plain":["6"]},"execution_count":20,"metadata":{},"output_type":"execute_result"}],"source":["len(fruit)"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"BCdYJtfCsNTk"},"source":["We can use negative indices, which count backward from the end of the string."]},{"cell_type":"code","execution_count":21,"metadata":{"id":"2kdWhLASsWjM"},"outputs":[{"data":{"text/plain":["('a', 'n')"]},"execution_count":21,"metadata":{},"output_type":"execute_result"}],"source":["fruit[-1], fruit[-2]"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"MZguDlIUuGmy"},"source":["Slicing also works on `string` to extract a substring from the original string. Remember that we can slice sequences using `[start:stop:step]`. The operator `[start:stop]` returns the part of the string from the “start-th” character to the “stop-th” character, including the first but excluding the last with `step=1`. If we omit the first index (before the colon), the slice starts at the beginning of the `string`. If we omit the second index, the slice goes to the end of the `string`:"]},{"cell_type":"code","execution_count":22,"metadata":{"id":"2fPn1ShJubZo"},"outputs":[{"name":"stdout","output_type":"stream","text":["Cool-\n","Python\n","Co-yhn\n","Cool-Python\n","nohtyP-looC\n"]}],"source":["s = 'Cool-Python'\n","\n","print(s[:5]) #same as s[0:5] \n","print(s[5:]) #same as s[5:len(s)] \n","print(s[::2]) #same as s[0:len(s):2]\n","print(s[::]) #same as s[:] and s[0:len(s):1] => copy the string\n","print(s[::-1]) #same as s[-1:-(len(s)+1):-1] => reverse the string"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"7RePo7y6wYjw"},"source":["`Strings` are \"immutable\", which means that it cannot be modified:"]},{"cell_type":"code","execution_count":23,"metadata":{"id":"uYrfWa9lwFFx"},"outputs":[{"ename":"TypeError","evalue":"'str' object does not support item assignment","output_type":"error","traceback":["\u001b[1;31m---------------------------------------------------------------------------\u001b[0m","\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)","\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_29596\\3977946057.py\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0ms\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"hello\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'y'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m","\u001b[1;31mTypeError\u001b[0m: 'str' object does not support item assignment"]}],"source":["s = \"hello\"\n","s[0] = 'y' "]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"775wqKWHwtGa"},"source":["The \"object\" in this case, is the `string` and the \"item\" is the character you tried to assign. The best you can do is create a new `string` that is a variation on the original:"]},{"cell_type":"code","execution_count":24,"metadata":{"id":"YuVQIH1XwfID"},"outputs":[{"name":"stdout","output_type":"stream","text":["1673653634096\n","1673687868400\n","yello\n"]}],"source":["print(id(s))\n","s = 'y' + s[1:len(s)]\n","print(id(s))\n","print(s)"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"zq-Y5gN7x64f"},"source":["A lot of computations involve processing a `string` one character at a time. Often they start at the beginning, select each character in turn, do something to it, and continue until the end. The traversal of `string` is just like we see before:"]},{"cell_type":"code","execution_count":25,"metadata":{"id":"22fq9pCezegR"},"outputs":[{"name":"stdout","output_type":"stream","text":["There is an o\n"]}],"source":["# Test if s contains 'o'\n","for char in s: # Retrieve item (character) one by one\n"," if char == 'o':\n"," print(\"There is an o\")\n"," break"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `in` and `not in` operators can be used with `strings` just like with `list`. An expression with two strings joined using `in` or `not in` will evaluate to a Boolean `True` or `False`:"]},{"cell_type":"code","execution_count":26,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["True\n","False\n"]}],"source":["print('Hello' in 'Hello, World')\n","print('cats' not in 'cats and dogs')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["### Escape Characters"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["An ***escape character*** lets you use characters that are otherwise impossible to put into a `string`. An escape character consists of a backslash (`\\`) followed by the character you want to add to the string. (Despite consisting of two characters, it is commonly referred to as a singular escape character.) For example, the escape character for a single quote is `\\'`. You can use this inside a string that begins and ends with single quotes"]},{"cell_type":"code","execution_count":33,"metadata":{},"outputs":[{"data":{"text/plain":["\"Say hi to Bob's mother.\""]},"execution_count":33,"metadata":{},"output_type":"execute_result"}],"source":["spam = 'Say hi to Bob\\'s mother.'\n","spam"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Python knows that since the single quote in `Bob\\'s` has a backslash, it is not a single quote meant to end the `string`. The escape characters `\\'` and `\\\"` let you put single quotes and double quotes inside your strings, respectively."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["
\n","\n","| Escape character | Prints as |\n","|------------------|----------------------|\n","| `\\'` | Single quote |\n","| `\\\"` | Double quote |\n","| `\\\\` | Backslash |\n","| `\\t` | Tab |\n","| `\\n` | Newline (line break) |\n","\n","
"]},{"cell_type":"code","execution_count":37,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Hello there!\n","How are you?\n","\tI'm doing fine.\n"]}],"source":["print(\"Hello there!\\nHow are you?\\n\\tI\\'m doing fine.\")"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["While you can use the `\\n` escape character to put a newline into a `string`, it is often easier to use ***multiline strings***. A multiline string in Python begins and ends with either three single quotes or three double quotes. Any quotes, tabs, or newlines in between the \"triple quotes\" are considered part of the `string`."]},{"cell_type":"code","execution_count":35,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Hello there,\n","How are you?\n"," I'm doing fine\n","\n"]}],"source":["print('''Hello there,\n","How are you?\n"," I'm doing fine\n","''')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Notice that the single quote character in `I'm` does not need to be escaped. Escaping single and double quotes is optional in multiline strings."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### Raw Strings"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["You can place an `r` before the beginning quotation mark of a `string` to make it a ***raw string***. **A raw string completely ignores all escape characters** and prints any backslash that appears in the `string`. "]},{"cell_type":"code","execution_count":43,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["That is Carol\\'s cat.\n"]}],"source":["print(r'That is Carol\\'s cat.')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Because this is a raw string, Python considers the backslash as part of the `string` and not as the start of an escape character. Raw strings are helpful if you are typing strings that contain many backslashes, such as the `strings` used for Windows file paths like `r'C:\\Users\\Al\\Desktop'`."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["### Putting Strings Inside Other Strings"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Putting `strings` inside other `strings` is a common operation in programming. So far, we've been using the `+` operator and string concatenation to do this:"]},{"cell_type":"code","execution_count":11,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","Hey! I'm Al, 33 old and I love Python Programing\n"]}],"source":["name = 'Al'\n","age = 33\n","language = 'Python'\n","print(\"\\nHey! I'm \" + name + \", \" + str(age)+ \" old and I love \" + language + \" Programing\")"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["However, this requires a lot of tedious typing. A simpler approach is to use ***string interpolation***. The format operator, `%` allows us to construct `strings`, replacing parts of the `strings` with the data stored in variables. **When applied to integers, `%` is the modulus operator. But when the first operand is a `string`, `%` is the format operator.**"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"HoP5PNW-9Jk_"},"source":["The first operand is the ***format string***, which contains one or more ***format specifiers*** that specify how the second operand is formatted. The result is a `string`. For example, the format specifiers `%d` means that the second operand should be formatted as an integer (\"d\" stands for \"decimal\"). One benefit is that `str()` doesn’t have to be called to convert values to `strings`:"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["
"]},{"cell_type":"code","execution_count":7,"metadata":{"id":"XUVfczP09OJR"},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","Hey! I'm Al, 33 years old and I love Python Programing\n"]}],"source":["print(\"\\nHey! I'm %s, %d years old and I love %s Programing\"%(name,age,language)) # Like the printf in C"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["We can have more control over the formatting, for instance:"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["
"]},{"cell_type":"code","execution_count":47,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["a= 32, b= 32.15\n"]}],"source":["a = 32\n","b = 32.145\n","print('a=%4d, b=%6.2f' % (a,b))"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["By default, Python right-aligns numbers and left-aligns other values such as strings. The numbers after `%` is the total field width and the field width for the decimal part (separated by `.`). For values with fewer characters than the field width, the remaining character positions are filled with spaces. The `%f` is used to format floating points and note that variable `b` has been rounded."]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"JQilFDZB9dPP"},"source":["Python 3.6 introduced ***f-strings*** (The `f` is for format), which is similar to string interpolation except that braces are used instead of `%s`, with the expressions placed directly inside the braces. Like raw strings, f-strings have an `f` prefix before the starting quotation mark. (Note that it is even possible to do inline arithmetic)"]},{"cell_type":"code","execution_count":13,"metadata":{"id":"qgfevIe19eHx"},"outputs":[{"name":"stdout","output_type":"stream","text":["\n","Hey! I'm Al, 35 years old and I love Python Programing\n"]}],"source":["print(f\"\\nHey! I'm {name}, {age+2} years old and I love {language} Programing\") "]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["We can have more control with the f-string besides the field width, like specifying left, right and center alignment with `<`, `>` and `^`. Note now the format specifiers are placed after the variable separated by a colon:"]},{"cell_type":"code","execution_count":50,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["[32 ]\n","[ 32.15 ]\n"]}],"source":["print(f'[{a:<15d}]')\n","print(f'[{b:^9.2f}]')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["In addition, you can use `+` before the field width specifies that a positive number should be preceded by a `+`. A negative number always starts with a `-`. To fill the remaining characters of the field with 0s rather than spaces, place a `0` before the field width (and after the `+` if there is one):"]},{"cell_type":"code","execution_count":51,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["[ +32]\n","[+000000032]\n"]}],"source":["print(f'[{a:+10d}]')\n","print(f'[{a:+010d}]')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["See https://docs.python.org/3/library/string.html#formatspec for more details."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["> Yet another is the `format()` method, see https://realpython.com/python-string-formatting/#toc for more details."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["### Exercise 1: Assuming we are designing a word game called \"The Mysterious Island\" and we need to print the statistics of the player each time the game begins. Try to complete the following function that receives the variables from the game and displays the information that right aligns with each other using the f-string:\n","\n","```\n","Player1 Stats:\n","Health: 100/100\n","Experience: 0/150\n","Gold: 50.00/60.00\n","\n","\n","Player2 Stats:\n","Health: 60/100\n","Experience: 120/150\n","Gold: 40.00/60.00\n","```\n","\n","Hint: You can first calculate the maximal width required for each row.\n","\n","\n","
"]},{"cell_type":"code","execution_count":54,"metadata":{},"outputs":[],"source":["def print_stats(player_name, health, experience, gold):\n"," print(f\"{player_name} Stats:\")\n"," print(f\"Health:____/100\")\n"," print(f\"Experience:______/150\")\n"," print(f\"Gold:_____/60.00\")"]},{"cell_type":"code","execution_count":55,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Welcome to \"The Mysterious Island\" adventure!\n","\n","\n","Player1 Stats:\n","Health: 100/100\n","Experience: 0/150\n","Gold: 50.00/60.00\n","\n","\n","Player2 Stats:\n","Health: 60/100\n","Experience: 120/150\n","Gold: 40.00/60.00\n"]}],"source":["game_title = \"The Mysterious Island\"\n","\n","welcome_message = f'Welcome to \"{game_title}\" adventure!\\n\\n'\n","# 1. Print the welcome_message\n","print(welcome_message)\n","\n","# 2. Use string and number formatting to print out the statistics\n","player_name = \"Player1\"\n","health = 100\n","experience = 0\n","gold = 50.000\n","\n","print_stats(player_name, health, experience, gold)\n","\n","print(\"\\n\")\n","\n","player_name = \"Player2\"\n","health = 60\n","experience = 120\n","gold = 40.0\n","\n","print_stats(player_name, health, experience, gold)"]},{"cell_type":"markdown","metadata":{"id":"DPpfFEA07W0A"},"source":["### String method"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"zFPpUx5w7al_"},"source":["`Strings` are an example of Python objects. An object contains both data (the actual `string` itself) and methods, which are effective functions that are built into the object and are available to any instance of the object."]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"894SyVBC7fbO"},"source":["Python has a function called `dir()`, which lists the methods available for an object. "]},{"cell_type":"code","execution_count":56,"metadata":{"id":"hfQPXKNF7ZzM"},"outputs":[{"data":{"text/plain":["['__add__',\n"," '__class__',\n"," '__contains__',\n"," '__delattr__',\n"," '__dir__',\n"," '__doc__',\n"," '__eq__',\n"," '__format__',\n"," '__ge__',\n"," '__getattribute__',\n"," '__getitem__',\n"," '__getnewargs__',\n"," '__gt__',\n"," '__hash__',\n"," '__init__',\n"," '__init_subclass__',\n"," '__iter__',\n"," '__le__',\n"," '__len__',\n"," '__lt__',\n"," '__mod__',\n"," '__mul__',\n"," '__ne__',\n"," '__new__',\n"," '__reduce__',\n"," '__reduce_ex__',\n"," '__repr__',\n"," '__rmod__',\n"," '__rmul__',\n"," '__setattr__',\n"," '__sizeof__',\n"," '__str__',\n"," '__subclasshook__',\n"," 'capitalize',\n"," 'casefold',\n"," 'center',\n"," 'count',\n"," 'encode',\n"," 'endswith',\n"," 'expandtabs',\n"," 'find',\n"," 'format',\n"," 'format_map',\n"," 'index',\n"," 'isalnum',\n"," 'isalpha',\n"," 'isascii',\n"," 'isdecimal',\n"," 'isdigit',\n"," 'isidentifier',\n"," 'islower',\n"," 'isnumeric',\n"," 'isprintable',\n"," 'isspace',\n"," 'istitle',\n"," 'isupper',\n"," 'join',\n"," 'ljust',\n"," 'lower',\n"," 'lstrip',\n"," 'maketrans',\n"," 'partition',\n"," 'removeprefix',\n"," 'removesuffix',\n"," 'replace',\n"," 'rfind',\n"," 'rindex',\n"," 'rjust',\n"," 'rpartition',\n"," 'rsplit',\n"," 'rstrip',\n"," 'split',\n"," 'splitlines',\n"," 'startswith',\n"," 'strip',\n"," 'swapcase',\n"," 'title',\n"," 'translate',\n"," 'upper',\n"," 'zfill']"]},"execution_count":56,"metadata":{},"output_type":"execute_result"}],"source":["dir(s)"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"BtXyvNIT7ncg"},"source":["While the `dir()` function lists the methods, and you can use `help()` to get some simple documentation on a method, a better source of documentation for `string` methods would be https://docs.python.org/library/stdtypes.html#string-methods."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### The `upper()`, `lower()` Methods"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `upper()` and `lower()` string methods return a **new `string`** where all the letters in the original `string` have been converted to uppercase or lowercase:"]},{"cell_type":"code","execution_count":57,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["HELLO, WORLD!\n","hello, world!\n"]}],"source":["spam = 'Hello, world!'\n","spam = spam.upper()\n","print(spam)\n","spam = spam.lower()\n","print(spam)"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Note that these methods do not change the `string` itself but return new `string` values. If you want to change the original `string`, you have to call `upper()` or `lower()` on the string and then assign the new string to the variable where the original was stored. This is why you must use `spam = spam.upper()` to change the string in spam instead of simply `spam.upper()`. (This is just like if a variable `eggs` contains the value 10. Writing `eggs + 3` does not change the value of `eggs`, but `eggs = eggs + 3` does.). These data types are immutable and can not be modified in-place."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `upper()` and `lower()` methods are helpful if you need **to make a case-insensitive comparison**. For example, the strings `'great'` and `'GREat'` are not equal to each other. But in the following small program, it does not matter whether the user types `Great`, `GREAT`, or `grEAT`, because the `string` is first converted to lowercase."]},{"cell_type":"code","execution_count":59,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["How are you?\n","I feel great too.\n"]}],"source":["print('How are you?')\n","feeling = input()\n","if feeling.lower() == 'great':\n"," print('I feel great too.')\n","else:\n"," print('I hope the rest of your day is good.')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### The `isX()` Methods"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["There are several other `string` methods that have names beginning with the word `is`. These methods return a Boolean value that describes the nature of the `string`. Here are some common `isX()` string methods:"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["- `isupper()/islower()` Returns `True` if the string has at least one letter and all the letters are uppercase or lowercase\n","\n","- `isalpha()` Returns `True` if the string consists only of letters and isn't blank\n","\n","- `isalnum()` Returns `True` if the string consists only of letters and numbers and is not blank\n","\n","- `isdecimal()` Returns `True` if the string consists only of numeric characters and is not blank\n","\n","- `isspace()` Returns `True` if the string consists only of spaces, tabs, and newlines and is not blank\n","\n","- `istitle()` Returns `True` if the string consists only of words that begin with an uppercase letter followed by only lowercase letters"]},{"cell_type":"code","execution_count":61,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["False\n","True\n","True\n","True\n","False\n","True\n","True\n"]}],"source":["print('Hello, world!'.islower()) \n","print('hello, world!'.islower())\n","print('hello'.isalpha())\n","print('hello123'.isalnum())\n","print('hello123'.isdecimal())\n","print(' '.isspace())\n","print('This Is Title Case'.istitle())"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `isX()` string methods are helpful when you need to validate user input. For example, the following program repeatedly asks users for their `age` and a `password` until they provide valid input:"]},{"cell_type":"code","execution_count":62,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["Enter your age:\n","Please enter a number for your age.\n","Enter your age:\n","Please enter a number for your age.\n","Enter your age:\n","Select a new password (letters and numbers only):\n","Passwords can only have letters and numbers.\n","Select a new password (letters and numbers only):\n"]}],"source":["while True:\n"," print('Enter your age:')\n"," age = input()\n"," if age.isdecimal():\n"," break\n"," print('Please enter a number for your age.')\n","\n","while True:\n"," print('Select a new password (letters and numbers only):')\n"," password = input()\n"," if password.isalnum():\n"," break\n"," print('Passwords can only have letters and numbers.')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["In the first while loop, we ask the user for their age and store their input in `age`. If `age` is a valid (decimal) value, we break out of this first while loop and move on to the second, which asks for a `password`. Otherwise, we inform the user that they need to enter a number and again ask them to enter their `age`. In the second while loop, we ask for a `password`, store the user's input in `password`, and break out of the loop if the input is alphanumeric. If it wasn't, we're not satisfied, so we tell the user the `password` needs to be alphanumeric and again ask them to enter a password."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### The `startswith()` and `endswith()` Methods"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `startswith()` and `endswith()` methods return `True` if the `string` they are called on begins or ends (respectively) with the `string` passed to the method; otherwise, they return `False`:"]},{"cell_type":"code","execution_count":14,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["True\n","False\n"]}],"source":["print('Hello, world!'.startswith('Hello'))\n","print('abc123'.endswith('12'))"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### The `replace()` methods"]},{"attachments":{},"cell_type":"markdown","metadata":{"id":"M-PIrdKX-Kz_"},"source":["The `replace()` function is like a “search and replace” operation in a word processor:"]},{"cell_type":"code","execution_count":15,"metadata":{"id":"GOiICZMo-Mn-"},"outputs":[{"name":"stdout","output_type":"stream","text":["Hello Jane\n"]}],"source":["greet = 'Hello Bob'\n","nstr = greet.replace('Bob','Jane')\n","print(nstr)"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### The `join()` and `split()` Methods"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `join()` method is useful when you have a list of strings that need to be joined together into a single `string`. The `join()` method is called on a `string`, gets passed a list of strings, and returns a `string`. The returned `string` is the concatenation of each `string` in the passed-in list. "]},{"cell_type":"code","execution_count":24,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["cats, rats, bats\n","My name is Simon\n"]}],"source":["print(', '.join(['cats', 'rats', 'bats'])) #Separated by comma\n","print(' '.join(['My', 'name', 'is', 'Simon'])) #Separated by white space"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Notice that the string `join()` calls on is inserted between each string of the list argument. For example, when `join(['cats', 'rats', 'bats'])` is called on the `', '` string, the returned string is `'cats, rats, bats'`."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["The `split()` method does the opposite: It’s called on a string and returns a list of strings."]},{"cell_type":"code","execution_count":17,"metadata":{},"outputs":[{"data":{"text/plain":["['My', 'name', 'is', 'Simon']"]},"execution_count":17,"metadata":{},"output_type":"execute_result"}],"source":["'My name is Simon'.split()"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["By default, the `string` 'My name is Simon' is split wherever whitespace characters such as the space, tab, or newline characters are found. These whitespace characters are not included in the strings in the returned list. You can pass a delimiter string to the `split()` method to specify a different string to split upon:"]},{"cell_type":"code","execution_count":22,"metadata":{},"outputs":[{"data":{"text/plain":["['cats', ' rats', ' bats']"]},"execution_count":22,"metadata":{},"output_type":"execute_result"}],"source":["'cats, rats, bats'.split(',')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["A common use of `split()` is to split a multiline string along the newline characters:"]},{"cell_type":"code","execution_count":25,"metadata":{},"outputs":[{"data":{"text/plain":["['Dear Alice,',\n"," 'How have you been? I am fine.',\n"," 'There is a container in the fridge',\n"," 'that is labeled \"Milk Experiment.\"',\n"," '',\n"," 'Please do not drink it.',\n"," 'Sincerely,',\n"," 'Bob']"]},"execution_count":25,"metadata":{},"output_type":"execute_result"}],"source":["spam = '''Dear Alice,\n","How have you been? I am fine.\n","There is a container in the fridge\n","that is labeled \"Milk Experiment.\"\n","\n","Please do not drink it.\n","Sincerely,\n","Bob'''\n","\n","spam.split('\\n')"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Passing `split()` the argument `'\\n'` lets us split the multiline string stored in `spam` along the newlines and return a list in which each item corresponds to one line of the `string`."]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["#### Removing Whitespace with the `strip()`, `lstrip()` and `rstrip()` Methods"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Sometimes you may want to strip off whitespace characters (space, tab, and newline) from the left side, right side, or both sides of a string. The `strip()` string method will return a new string without any whitespace characters at the beginning or end. The `lstrip()` and `rstrip()` methods will remove whitespace characters from the left and right ends, respectively."]},{"cell_type":"code","execution_count":26,"metadata":{"id":"klCtkrIZIgB3"},"outputs":[{"data":{"text/plain":["'Hello, World'"]},"execution_count":26,"metadata":{},"output_type":"execute_result"}],"source":["spam = ' Hello, World '\n","spam.strip()"]},{"cell_type":"code","execution_count":27,"metadata":{},"outputs":[{"data":{"text/plain":["'Hello, World '"]},"execution_count":27,"metadata":{},"output_type":"execute_result"}],"source":["spam.lstrip()"]},{"cell_type":"code","execution_count":28,"metadata":{},"outputs":[{"data":{"text/plain":["' Hello, World'"]},"execution_count":28,"metadata":{},"output_type":"execute_result"}],"source":["spam.rstrip()"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["### Exercise 2: When editing the markdown document, you can create a bulleted list by putting each list item on its own line and placing a `-` in front. But say you have a really large list to which you want to add bullet points. You could just type those `-` at the beginning of each line, one by one. Or you could automate this task with a short Python program! For example, if I have following text:\n","\n","```\n","Lists of resources\n","Lists of books\n","Lists of videos\n","Lists of blogs\n","```\n","\n","After running the program, the text should contain the following:\n","\n","```\n","- Lists of resources\n","- Lists of books\n","- Lists of videos\n","- Lists of blogs\n","```\n","\n","
"]},{"cell_type":"code","execution_count":30,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":["- Lists of resources\n","- Lists of books\n","- Lists of videos\n","- Lists of blogs\n"]}],"source":["text = \"\"\"Lists of resources\n","Lists of books\n","Lists of videos\n","Lists of blogs\"\"\"\n","\n","# 1. Separate lines into list using string method.\n","lines = text.________\n","\n","# 2. Add -\n","for i, line in enumerate(lines): # loop through all indexes for \"lines\" list\n"," lines[i] = ________ # add - to each string in \"lines\" list\n","\n","# 3. Use string method to conctenate list of strings back to string\n","text = _____________\n","print(text)"]},{"attachments":{},"cell_type":"markdown","metadata":{},"source":["Text is a common form of data, and Python comes with many helpful string methods to process the text stored in `string`. You will make use of indexing, slicing, and string methods in almost every Python program you write. The programs you are writing now don’t seem too sophisticated—they don’t have graphical user interfaces with images and colorful text. So far, you’re displaying text with `print()` and letting the user enter text with `input()`. However, another way to manipulate large amounts of text is by reading and writing files directly off the hard drive. You’ll learn how to do this with Python later on.\n","\n","That just about covers all the basic concepts of Python programming! You’ll continue to learn new concepts throughout the rest of this course, but you now know enough to start writing some useful programs that can automate tasks. If you’d like to see a collection of short, simple Python programs built from the basic concepts you’ve learned so far, check out https://github.com/asweigart/pythonstdiogames/. Try copying the source code for each program by hand and then make modifications to see how they affect the behavior of the program. Once you have an understanding of how the program works, try re-creating the program yourself from scratch. You don’t need to re-create the source code exactly; just focus on what the program does rather than how it does it."]}],"metadata":{"colab":{"collapsed_sections":["SwFKFBMwRzoa","n3ezAAdIsgpj","gASYx5-Cxzyg","2kLRVhae3rSa","DPpfFEA07W0A","uloOTsPL9A74","MTJO4K049nuU","3hD9uBt6AW9l","IvviPig3At12","HQK5zGP749m3","7YVyJ-IgBZ7s","L5VlI3VKg_dV","wgqoOGqEiUre","jscaE3K65HP9","UMo588t4rY-O","AGs4jgnSsZa1"],"provenance":[],"toc_visible":true},"kernelspec":{"display_name":"base","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.9.13"},"vscode":{"interpreter":{"hash":"1561eddc5e0c9c74df968f74d5080d02882967127f956e6e7049c43d2ef42321"}}},"nbformat":4,"nbformat_minor":0}